home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / ModulationSpecifier.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  11.5 KB  |  312 lines  |  [TEXT/KAHL]

  1. /* ModulationSpecifier.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "ModulationSpecifier.h"
  31. #include "Memory.h"
  32. #include "OscillatorSpecifier.h"
  33. #include "OscillatorListSpecifier.h"
  34. #include "DataMunging.h"
  35. #include "Envelope.h"
  36. #include "LFOListSpecifier.h"
  37.  
  38.  
  39. typedef struct
  40.     {
  41.         /* how are the streams being modulated */
  42.         ModulationTypes            ModulationType;
  43.  
  44.         /* which connection in the oscillator is being modulated */
  45.         ModDestTypes                ModulationDestination;
  46.  
  47.         /* multiply our output by this before modulating (for magnitude control) */
  48.         EnvelopeRec*                ScalingFactorEnvelope;
  49.         LFOListSpecRec*            ScalingFactorLFOList;
  50.  
  51.         /* add this to our output before modulating (for incompleteness) */
  52.         EnvelopeRec*                OriginAdjustEnvelope;
  53.         LFOListSpecRec*            OriginAdjustLFOList;
  54.  
  55.         /* what oscillator are we modulating */
  56.         char*                                InputOscillatorName;
  57.  
  58.         /* reference to the oscillator being input from.  this is not made up */
  59.         /* to date until the whole tree has been built. */
  60.         OscillatorRec*            InputOscillatorReference;
  61.     } ModEntryRec;
  62.  
  63.  
  64. struct ModulationSpecRec
  65.     {
  66.         long                                NumEntries;
  67.         ModEntryRec*                ArrayOfSources;
  68.     };
  69.  
  70.  
  71. /* create new list of modulation source specifiers */
  72. ModulationSpecRec*        NewModulationSpecifier(void)
  73.     {
  74.         ModulationSpecRec*    ModSpec;
  75.  
  76.         ModSpec = (ModulationSpecRec*)AllocPtrCanFail(sizeof(ModulationSpecRec),
  77.             "ModulationSpecRec");
  78.         if (ModSpec == NIL)
  79.             {
  80.              FailurePoint1:
  81.                 return NIL;
  82.             }
  83.         ModSpec->ArrayOfSources = (ModEntryRec*)AllocPtrCanFail(0,"ModEntryRec");
  84.         if (ModSpec->ArrayOfSources == NIL)
  85.             {
  86.              FailurePoint2:
  87.                 ReleasePtr((char*)ModSpec);
  88.                 goto FailurePoint1;
  89.             }
  90.         ModSpec->NumEntries = 0;
  91.         return ModSpec;
  92.     }
  93.  
  94.  
  95. /* dispose a list of modulation source specifiers */
  96. void                                    DisposeModulationSpecifier(ModulationSpecRec* ModSpec)
  97.     {
  98.         long                                Scan;
  99.  
  100.         CheckPtrExistence(ModSpec);
  101.         for (Scan = 0; Scan < ModSpec->NumEntries; Scan += 1)
  102.             {
  103.                 ReleasePtr(ModSpec->ArrayOfSources[Scan].InputOscillatorName);
  104.                 DisposeEnvelope(ModSpec->ArrayOfSources[Scan].ScalingFactorEnvelope);
  105.                 DisposeEnvelope(ModSpec->ArrayOfSources[Scan].OriginAdjustEnvelope);
  106.                 DisposeLFOListSpecifier(ModSpec->ArrayOfSources[Scan].ScalingFactorLFOList);
  107.                 DisposeLFOListSpecifier(ModSpec->ArrayOfSources[Scan].OriginAdjustLFOList);
  108.             }
  109.         ReleasePtr((char*)ModSpec->ArrayOfSources);
  110.         ReleasePtr((char*)ModSpec);
  111.     }
  112.  
  113.  
  114. /* append a new entry.  the object becomes owner of the name */
  115. MyBoolean                            AppendModulationSpecEntry(ModulationSpecRec* ModSpec,
  116.                                                 ModulationTypes ModulationType,
  117.                                                 ModDestTypes ModulationDestination,
  118.                                                 struct EnvelopeRec* ScalingEnvelope,
  119.                                                 struct LFOListSpecRec* ScalingLFOList,
  120.                                                 struct EnvelopeRec* OriginAdjustEnvelope,
  121.                                                 struct LFOListSpecRec* OriginAdjustLFOList,
  122.                                                 char* InputOscillatorName)
  123.     {
  124.         ModEntryRec*                NewArray;
  125.  
  126.         CheckPtrExistence(ModSpec);
  127.         CheckPtrExistence(InputOscillatorName);
  128.         CheckPtrExistence(ScalingEnvelope);
  129.         CheckPtrExistence(ScalingLFOList);
  130.         CheckPtrExistence(OriginAdjustEnvelope);
  131.         CheckPtrExistence(OriginAdjustLFOList);
  132.         NewArray = (ModEntryRec*)ResizePtr((char*)ModSpec->ArrayOfSources,
  133.             sizeof(ModEntryRec) * (1 + ModSpec->NumEntries));
  134.         if (NewArray == NIL)
  135.             {
  136.                 return False;
  137.             }
  138.         ModSpec->ArrayOfSources = NewArray;
  139.         ModSpec->ArrayOfSources[ModSpec->NumEntries].ModulationType = ModulationType;
  140.         ModSpec->ArrayOfSources[ModSpec->NumEntries].ModulationDestination
  141.             = ModulationDestination;
  142.         ModSpec->ArrayOfSources[ModSpec->NumEntries].ScalingFactorEnvelope = ScalingEnvelope;
  143.         ModSpec->ArrayOfSources[ModSpec->NumEntries].ScalingFactorLFOList = ScalingLFOList;
  144.         ModSpec->ArrayOfSources[ModSpec->NumEntries].OriginAdjustEnvelope = OriginAdjustEnvelope;
  145.         ModSpec->ArrayOfSources[ModSpec->NumEntries].OriginAdjustLFOList = OriginAdjustLFOList;
  146.         ModSpec->ArrayOfSources[ModSpec->NumEntries].InputOscillatorName
  147.             = InputOscillatorName;
  148.         ModSpec->NumEntries += 1;
  149.         return True;
  150.     }
  151.  
  152.  
  153. /* get the total number of entries in the modulation list */
  154. long                                    GetModulationSpecNumEntries(ModulationSpecRec* ModSpec)
  155.     {
  156.         CheckPtrExistence(ModSpec);
  157.         return ModSpec->NumEntries;
  158.     }
  159.  
  160.  
  161. /* resolve named references into actual oscillator references.  returns False */
  162. /* if a name couldn't be resolved. */
  163. MyBoolean                            ResolveModulationReferences(ModulationSpecRec* ModSpec,
  164.                                                 struct OscillatorListRec* OscillatorList)
  165.     {
  166.         long                                ModScan;
  167.         long                                OscLimit;
  168.  
  169.         CheckPtrExistence(ModSpec);
  170.         CheckPtrExistence(OscillatorList);
  171.  
  172.         OscLimit = GetOscillatorListLength(OscillatorList);
  173.         for (ModScan = 0; ModScan < ModSpec->NumEntries; ModScan += 1)
  174.             {
  175.                 long                                OscScan;
  176.                 OscillatorRec*            PossibleOscillator;
  177.  
  178.                 for (OscScan = 0; OscScan < OscLimit; OscScan += 1)
  179.                     {
  180.                         char*                                OscillatorName;
  181.  
  182.                         PossibleOscillator = GetOscillatorFromList(OscillatorList,OscScan);
  183.                         OscillatorName = OscillatorGetName(PossibleOscillator);
  184.                         PRNGCHK(ModSpec->ArrayOfSources,&(ModSpec->ArrayOfSources[ModScan].
  185.                             InputOscillatorName),sizeof(ModSpec->ArrayOfSources[ModScan].
  186.                             InputOscillatorName));
  187.                         if (PtrSize(OscillatorName) == PtrSize(ModSpec->ArrayOfSources[ModScan].
  188.                             InputOscillatorName))
  189.                             {
  190.                                 if (MemEqu(OscillatorName,ModSpec->ArrayOfSources[ModScan].
  191.                                     InputOscillatorName,PtrSize(OscillatorName)))
  192.                                     {
  193.                                         /* found it */
  194.                                         ModSpec->ArrayOfSources[ModScan].InputOscillatorReference
  195.                                             = PossibleOscillator;
  196.                                         goto FoundItPoint;
  197.                                     }
  198.                             }
  199.                     }
  200.                 return False; /* oops, an unresolved one */
  201.              FoundItPoint:
  202.                 ;
  203.             }
  204.  
  205.         return True;
  206.     }
  207.  
  208.  
  209. /* get the modulation type of one of the sources */
  210. ModulationTypes                GetModulationOpType(ModulationSpecRec* ModSpec, long Index)
  211.     {
  212.         CheckPtrExistence(ModSpec);
  213.         ERROR((Index < 0) || (Index >= ModSpec->NumEntries),PRERR(ForceAbort,
  214.             "GetModulationOpType:  index out of range"));
  215.         PRNGCHK(ModSpec->ArrayOfSources,&(ModSpec->ArrayOfSources[Index]),
  216.             sizeof(ModSpec->ArrayOfSources[Index]));
  217.         return ModSpec->ArrayOfSources[Index].ModulationType;
  218.     }
  219.  
  220.  
  221. /* get the destination of the modulation */
  222. ModDestTypes                    GetModulationDestType(ModulationSpecRec* ModSpec, long Index)
  223.     {
  224.         CheckPtrExistence(ModSpec);
  225.         ERROR((Index < 0) || (Index >= ModSpec->NumEntries),PRERR(ForceAbort,
  226.             "GetModulationDestType:  index out of range"));
  227.         PRNGCHK(ModSpec->ArrayOfSources,&(ModSpec->ArrayOfSources[Index]),
  228.             sizeof(ModSpec->ArrayOfSources[Index]));
  229.         return ModSpec->ArrayOfSources[Index].ModulationDestination;
  230.     }
  231.  
  232.  
  233. /* get the oscillator name for one of the sources (this is the original string) */
  234. char*                                    GetModulationOscillatorName(ModulationSpecRec* ModSpec, long Index)
  235.     {
  236.         CheckPtrExistence(ModSpec);
  237.         ERROR((Index < 0) || (Index >= ModSpec->NumEntries),PRERR(ForceAbort,
  238.             "GetModulationOscillatorName:  index out of range"));
  239.         PRNGCHK(ModSpec->ArrayOfSources,&(ModSpec->ArrayOfSources[Index]),
  240.             sizeof(ModSpec->ArrayOfSources[Index]));
  241.         return ModSpec->ArrayOfSources[Index].InputOscillatorName;
  242.     }
  243.  
  244.  
  245. /* get the actual oscillator reference for one of the sources */
  246. struct OscillatorRec*    GetModulationOscillatorRef(ModulationSpecRec* ModSpec, long Index)
  247.     {
  248.         CheckPtrExistence(ModSpec);
  249.         ERROR((Index < 0) || (Index >= ModSpec->NumEntries),PRERR(ForceAbort,
  250.             "GetModulationOscillatorRef:  index out of range"));
  251.         PRNGCHK(ModSpec->ArrayOfSources,&(ModSpec->ArrayOfSources[Index]),
  252.             sizeof(ModSpec->ArrayOfSources[Index]));
  253.         CheckPtrExistence(ModSpec->ArrayOfSources[Index].InputOscillatorReference);
  254.         return ModSpec->ArrayOfSources[Index].InputOscillatorReference;
  255.     }
  256.  
  257.  
  258. /* get the scaling factor envelope */
  259. struct EnvelopeRec*        GetModulationScalingFactorEnvelope(ModulationSpecRec* ModSpec,
  260.                                                 long Index)
  261.     {
  262.         CheckPtrExistence(ModSpec);
  263.         ERROR((Index < 0) || (Index >= ModSpec->NumEntries),PRERR(ForceAbort,
  264.             "GetModulationScalingFactorEnvelope:  index out of range"));
  265.         PRNGCHK(ModSpec->ArrayOfSources,&(ModSpec->ArrayOfSources[Index]),
  266.             sizeof(ModSpec->ArrayOfSources[Index]));
  267.         CheckPtrExistence(ModSpec->ArrayOfSources[Index].ScalingFactorEnvelope);
  268.         return ModSpec->ArrayOfSources[Index].ScalingFactorEnvelope;
  269.     }
  270.  
  271.  
  272. /* get the scaling factor LFO list */
  273. struct LFOListSpecRec*    GetModulationScalingFactorLFOList(ModulationSpecRec* ModSpec,
  274.                                                 long Index)
  275.     {
  276.         CheckPtrExistence(ModSpec);
  277.         ERROR((Index < 0) || (Index >= ModSpec->NumEntries),PRERR(ForceAbort,
  278.             "GetModulationScalingFactorLFOList:  index out of range"));
  279.         PRNGCHK(ModSpec->ArrayOfSources,&(ModSpec->ArrayOfSources[Index]),
  280.             sizeof(ModSpec->ArrayOfSources[Index]));
  281.         CheckPtrExistence(ModSpec->ArrayOfSources[Index].ScalingFactorLFOList);
  282.         return ModSpec->ArrayOfSources[Index].ScalingFactorLFOList;
  283.     }
  284.  
  285.  
  286. /* get the origin adjust envelope */
  287. struct EnvelopeRec*        GetModulationOriginAdjustEnvelope(ModulationSpecRec* ModSpec,
  288.                                                 long Index)
  289.     {
  290.         CheckPtrExistence(ModSpec);
  291.         ERROR((Index < 0) || (Index >= ModSpec->NumEntries),PRERR(ForceAbort,
  292.             "GetModulationOriginAdjustEnvelope:  index out of range"));
  293.         PRNGCHK(ModSpec->ArrayOfSources,&(ModSpec->ArrayOfSources[Index]),
  294.             sizeof(ModSpec->ArrayOfSources[Index]));
  295.         CheckPtrExistence(ModSpec->ArrayOfSources[Index].OriginAdjustEnvelope);
  296.         return ModSpec->ArrayOfSources[Index].OriginAdjustEnvelope;
  297.     }
  298.  
  299.  
  300. /* get the origin adjust LFO list */
  301. struct LFOListSpecRec*    GetModulationOriginAdjustLFOList(ModulationSpecRec* ModSpec,
  302.                                                 long Index)
  303.     {
  304.         CheckPtrExistence(ModSpec);
  305.         ERROR((Index < 0) || (Index >= ModSpec->NumEntries),PRERR(ForceAbort,
  306.             "GetModulationOriginAdjustLFOList:  index out of range"));
  307.         PRNGCHK(ModSpec->ArrayOfSources,&(ModSpec->ArrayOfSources[Index]),
  308.             sizeof(ModSpec->ArrayOfSources[Index]));
  309.         CheckPtrExistence(ModSpec->ArrayOfSources[Index].OriginAdjustLFOList);
  310.         return ModSpec->ArrayOfSources[Index].OriginAdjustLFOList;
  311.     }
  312.